/**
 * Cesium模型管理器 - 集成自定义createModelPrimitive函数
 */

export class CesiumModelManager {
    /**
     * 构造函数
     * @param {Cesium.Viewer} viewer - Cesium Viewer实例
     */
    constructor(viewer) {
        this.viewer = viewer;
        this.models = new Map(); // 存储模型信息，key为id
        this.primitives = new Cesium.PrimitiveCollection();
        viewer.scene.primitives.add(this.primitives);

        // 预定义颜色（用于标签和连接线）
        this.colors = [
            new Cesium.Color(1, 0, 0, 0.8),    // 红
            new Cesium.Color(0, 1, 0, 0.8),    // 绿
            new Cesium.Color(0, 0, 1, 0.8),    // 蓝
            new Cesium.Color(1, 1, 0, 0.8),    // 黄
            new Cesium.Color(1, 0, 1, 0.8),    // 品红
            new Cesium.Color(0, 1, 1, 0.8)     // 青
        ];
    }

    /**
     * 单入口方法 - 处理模型的创建和更新
     * @param {Object} param - 参数对象
     * @returns {Boolean} 操作是否成功
     */
    handleModel(param) {
        // 验证参数
        if (!param || !param.id || !param.positions || !param.url) {
            console.error('无效参数，需要包含id、positions和url');
            return false;
        }

        // 解析位置信息为函数所需格式
        const [lon, lat, hei] = param.positions;
        const position = { lon, lat, hei: hei || 0 };

        // 检查模型是否已存在
        if (this.models.has(param.id)) {
            // 模型已存在，更新位置
            return this.updateModel(param.id, position, param.text);
        } else {
            // 模型不存在，创建新模型
            return this.createModel(param.id, position, param.text, param.url, param.scale);
        }
    }

    /**
     * 创建新模型
     * @param {String} id - 模型ID
     * @param {Object} position - 位置 {lon, lat, hei}
     * @param {String} text - 标签文本
     * @param {String} url - 模型URL
     * @param {Number} [scale=1.0] - 缩放比例
     * @returns {Boolean} 是否创建成功
     */
    async createModel(id, position, text, url, scale = 1.0) {
        try {
            // 选择颜色
            const colorIndex = Math.abs(this.stringHash(id)) % this.colors.length;
            const modelColor = this.colors[colorIndex];

            // 使用自定义的createModelPrimitive函数加载模型
            const model = await this.createModelPrimitive({
                id,
                url,
                position,
                scale,
                color: modelColor
            });

            // 模型加载成功后处理
            this._onModelLoaded(id, position, text, modelColor, model);
            return true;
        } catch (error) {
            console.error(`创建模型 ${id} 失败:`, error);
            this._showLoadErrorToast(id, '模型加载失败');
            return false;
        }
    }

    /**
     * 自定义模型加载函数（替换原loadModelFromUrl）
     * @param {Object} options - 模型加载选项
     * @returns {Promise<Cesium.Model>} 模型实例
     */
    async createModelPrimitive(options) {
        const { id, url, position, scale = 1.0, color, height = 0 } = options;

        // 验证必要参数
        if (!url) {
            throw new Error(`模型 ${id} 缺少URL参数`);
        }

        if (!position || !position.lon || !position.lat) {
            throw new Error(`模型 ${id} 位置参数不完整`);
        }

        // 创建模型矩阵
        const modelMatrix = Cesium.Transforms.eastNorthUpToFixedFrame(
            Cesium.Cartesian3.fromDegrees(position.lon, position.lat, position.hei || height)
        );

        try {
            // 使用Cesium.Model.fromGltf加载模型
            const model = await Cesium.Model.fromGltf({
                url: url,
                modelMatrix: modelMatrix,
                scale: scale,
                maximumScale: 100000,
                minimumPixelSize: 64,
                color: color || Cesium.Color.WHITE,
                silhouetteColor: Cesium.Color.RED,
                silhouetteSize: 10.0,
                heightReference: Cesium.HeightReference.NONE,
                debugShowBoundingVolume: false,
                debugWireframe: false
            });

            // 添加模型到场景
            this.viewer.scene.primitives.add(model);

            // 创建标签
            const { pixelSize = 50 } = options;
            const labelCollection = new Cesium.LabelCollection({
                scene: this.viewer.scene
            });

            const label = labelCollection.add({
                position: Cesium.Cartesian3.fromDegrees(position.lon, position.lat, position.hei || height),
                text: options.text || '未命名模型',
                font: '14pt Arial',
                pixelOffset: new Cesium.Cartesian2(0, -pixelSize / 2 - 10),
                fillColor: Cesium.Color.WHITE,
                outlineColor: Cesium.Color.BLACK,
                outlineWidth: 2,
                style: Cesium.LabelStyle.FILL_AND_OUTLINE,
                showBackground: true,
                backgroundColor: new Cesium.Color.fromCssColorString("rgba(1,33,22,1)")
            });

            this.viewer.scene.primitives.add(labelCollection);

            // 存储标签信息到模型对象
            model.label = label;
            model.labelCollection = labelCollection;
            model.id = id;

            console.log(`模型 ${id} 加载成功`);
            return model;

        } catch (error) {
            console.error(`模型 ${id} 加载失败:`, error);
            throw error;
        }
    }

    /**
     * 模型加载完成后的处理
     */
    _onModelLoaded(id, position, text, color, model) {
        // 转换位置格式为Cartesian3
        const cartesianPosition = Cesium.Cartesian3.fromDegrees(
            position.lon,
            position.lat,
            position.hei || 0
        );

        // 创建连接线（模型到标签）
        const linePrimitive = this.createLinePrimitive(
            id,
            cartesianPosition,
            model.label.position._value // 获取标签位置
        );

        // 初始化路径数组
        const path = [cartesianPosition.clone()];

        // 创建路径Primitive
        const pathPrimitive = this.createPathPrimitive(id, path, color.withAlpha(0.5));

        // 存储模型信息
        const modelInfo = {
            id,
            position: cartesianPosition,
            modelPrimitive: model,
            labelPrimitive: model.label,
            labelCollection: model.labelCollection,
            linePrimitive,
            pathPrimitive,
            path: path,
            isDragging: false,
            text: text || '未命名模型',
            targetPosition: null,
            color: color
        };

        this.models.set(id, modelInfo);

        // 设置拖拽事件
        this.setupDragEvents(modelInfo);

        // 启动平滑更新
        this.startModelUpdate(id);
    }

    /**
     * 创建连接线Primitive
     */
    createLinePrimitive(id, modelPos, labelPos) {
        const linePrimitive = new Cesium.Primitive({
            geometryInstances: new Cesium.GeometryInstance({
                geometry: new Cesium.PolylineGeometry({
                    positions: [modelPos, labelPos],
                    width: 2,
                    vertexFormat: Cesium.PolylineMaterialAppearance.VERTEX_FORMAT
                }),
                id: `line_${id}`
            }),
            appearance: new Cesium.PolylineMaterialAppearance({
                material: Cesium.Material.fromType('PolylineDash', {
                    color: new Cesium.Color(1.0, 1.0, 1.0, 0.7),
                    dashLength: 15
                }),
                translucent: true
            }),
            asynchronous: false
        });

        this.primitives.add(linePrimitive);
        return linePrimitive;
    }

    /**
     * 创建路径Primitive
     */
    createPathPrimitive(id, path, color) {
        if (path.length < 2) {
            return new Cesium.Primitive({ asynchronous: false });
        }

        const pathPrimitive = new Cesium.Primitive({
            geometryInstances: new Cesium.GeometryInstance({
                geometry: new Cesium.PolylineGeometry({
                    positions: path,
                    width: 3,
                    vertexFormat: Cesium.PolylineMaterialAppearance.VERTEX_FORMAT
                }),
                id: `path_${id}`
            }),
            appearance: new Cesium.PolylineMaterialAppearance({
                material: Cesium.Material.fromType('PolylineColor', {
                    color: color
                }),
                translucent: true
            }),
            asynchronous: false
        });

        this.primitives.add(pathPrimitive);
        return pathPrimitive;
    }

    /**
     * 更新模型位置
     */
    updateModel(id, newPosition, text) {
        if (!this.models.has(id)) {
            console.warn(`模型 ${id} 不存在`);
            return false;
        }

        const modelInfo = this.models.get(id);
        const newCartesianPosition = Cesium.Cartesian3.fromDegrees(
            newPosition.lon,
            newPosition.lat,
            newPosition.hei || 0
        );

        // 更新目标位置
        modelInfo.targetPosition = newCartesianPosition.clone();

        // 记录路径点
        if (modelInfo.path.length === 0 ||
            Cesium.Cartesian3.distance(modelInfo.path[modelInfo.path.length - 1], newCartesianPosition) > 1) {
            modelInfo.path.push(newCartesianPosition.clone());
            this.updatePathPrimitive(modelInfo);
        }

        // 更新标签文本
        if (text && text !== modelInfo.text) {
            modelInfo.text = text;
            modelInfo.labelPrimitive.text = text;
        }

        return true;
    }

    /**
     * 其他必要方法（保持与之前版本一致）
     */
    updatePathPrimitive(modelInfo) {
        if (this.primitives.contains(modelInfo.pathPrimitive)) {
            this.primitives.remove(modelInfo.pathPrimitive);
        }

        modelInfo.pathPrimitive = this.createPathPrimitive(
            modelInfo.id,
            modelInfo.path,
            modelInfo.color.withAlpha(0.5)
        );
    }

    setupDragEvents(modelInfo) {
        const viewer = this.viewer;
        const modelId = modelInfo.id;

        viewer.canvas.addEventListener('mousedown', (event) => {

            const pick = viewer.scene.pick(new Cesium.Cartesian2(event.clientX, event.clientY));
            if (Cesium.defined(pick) && (pick.id === modelId || pick.primitive === modelInfo.labelPrimitive)) {
                modelInfo.isDragging = true;
                viewer.canvas.style.cursor = 'grabbing';
                event.preventDefault();
            }
        });

        viewer.canvas.addEventListener('mousemove', (event) => {
            if (modelInfo.isDragging) {
                const newPosition = this.getPositionFromMouse(event);
                if (newPosition) {
                    modelInfo.targetPosition = newPosition;
                    event.preventDefault();
                }
            } else {
                const pick = viewer.scene.pick(new Cesium.Cartesian2(event.clientX, event.clientY));
                if (Cesium.defined(pick) && (pick.id === modelId || pick.primitive === modelInfo.labelPrimitive)) {
                    viewer.canvas.style.cursor = 'grab';
                }
            }
        });

        const endDrag = () => {
            if (modelInfo.isDragging) {
                modelInfo.isDragging = false;
                viewer.canvas.style.cursor = 'default';
            }
        };

        viewer.canvas.addEventListener('mouseup', endDrag);
        viewer.canvas.addEventListener('mouseleave', endDrag);
    }

    getPositionFromMouse(event) {
        const windowPosition = new Cesium.Cartesian2(event.clientX, event.clientY);
        const ray = this.viewer.camera.getPickRay(windowPosition);
        return this.viewer.scene.globe.pick(ray, this.viewer.scene);
    }

    startModelUpdate(id) {
        const update = () => {
            if (!this.models.has(id)) return;

            const modelInfo = this.models.get(id);
            if (!modelInfo.targetPosition) {
                requestAnimationFrame(update);
                return;
            }

            const distance = Cesium.Cartesian3.distance(modelInfo.position, modelInfo.targetPosition);

            if (distance > 0.5) {
                const newPosition = Cesium.Cartesian3.lerp(
                    modelInfo.position,
                    modelInfo.targetPosition,
                    0.1,
                    new Cesium.Cartesian3()
                );

                modelInfo.position = newPosition;
                modelInfo.modelPrimitive.modelMatrix = Cesium.Transforms.eastNorthUpToFixedFrame(newPosition);

                // 更新标签位置
                if (!modelInfo.isDragging) {
                    modelInfo.labelPrimitive.position = newPosition;
                }

                // 更新连接线
                this.updateLine(modelInfo);
            } else {
                modelInfo.position = modelInfo.targetPosition.clone();
                modelInfo.modelPrimitive.modelMatrix = Cesium.Transforms.eastNorthUpToFixedFrame(modelInfo.position);

                if (!modelInfo.isDragging) {
                    modelInfo.labelPrimitive.position = modelInfo.position;
                }

                this.updateLine(modelInfo);
                modelInfo.targetPosition = null;
            }

            requestAnimationFrame(update);
        };

        update();
    }

    updateLine(modelInfo) {
        if (this.primitives.contains(modelInfo.linePrimitive)) {
            this.primitives.remove(modelInfo.linePrimitive);
        }

        modelInfo.linePrimitive = this.createLinePrimitive(
            modelInfo.id,
            modelInfo.position,
            modelInfo.labelPrimitive.position._value
        );
    }

    stringHash(str) {
        let hash = 0;
        for (let i = 0; i < str.length; i++) {
            const char = str.charCodeAt(i);
            hash = ((hash << 5) - hash) + char;
            hash = hash & hash;
        }
        return hash;
    }

    removeModel(id) {
        if (!this.models.has(id)) {
            console.warn(`模型 ${id} 不存在`);
            return false;
        }

        const modelInfo = this.models.get(id);

        // 移除所有相关元素
        this.viewer.scene.primitives.remove(modelInfo.modelPrimitive);
        this.viewer.scene.primitives.remove(modelInfo.labelCollection);
        this.primitives.remove(modelInfo.linePrimitive);
        this.primitives.remove(modelInfo.pathPrimitive);

        this.models.delete(id);
        return true;
    }

    _showLoadErrorToast(id, message) {
        const toast = document.createElement('div');
        toast.style.position = 'fixed';
        toast.style.bottom = '20px';
        toast.style.left = '50%';
        toast.style.transform = 'translateX(-50%)';
        toast.style.backgroundColor = 'rgba(255, 0, 0, 0.8)';
        toast.style.color = 'white';
        toast.style.padding = '8px 16px';
        toast.style.borderRadius = '4px';
        toast.style.zIndex = '9999';
        toast.textContent = `模型 ${id} 加载失败: ${message}`;
        document.body.appendChild(toast);

        setTimeout(() => {
            document.body.removeChild(toast);
        }, 3000);
    }
}

// 加载示例模型
// setTimeout(() => {
//     window.modelManager.handleModel({
//         id: 'drone_001',
//         positions: [116.39, 39.9, 100],
//         text: '无人机A',
//         url: '/model/Cesium_Air.glb',
//         scale: 1.0
//     });
// }, 1000);
